package com.lanzhou.yuanfen.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lanzhou.yuanfen.exception.RollBackException;
import com.lanzhou.yuanfen.sys.entity.Role;
import com.lanzhou.yuanfen.sys.entity.RolePermission;
import com.lanzhou.yuanfen.sys.entity.UserRole;
import com.lanzhou.yuanfen.sys.mapper.RoleMapper;
import com.lanzhou.yuanfen.sys.mapper.RolePermissionMapper;
import com.lanzhou.yuanfen.sys.mapper.UserRoleMapper;
import com.lanzhou.yuanfen.sys.service.IRoleService;
import com.lanzhou.yuanfen.util.PlusHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lcllge
 * @since 2019-12-02
 */
@Service
@Transactional(propagation = Propagation.NESTED, isolation = Isolation.DEFAULT, rollbackFor = RollBackException.class)
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Override
    public void insertOrModify(Role role) {
        List<RolePermission> addRP = null;
        String roles = role.getPerms();
        String[] split = roles.split(",");
        Set<Long> addRole = getPermKey(split);
        Set<Long> afterCopy = getPermKey(split);
        Long roleKey = role.getRoleKey();
        if (roleKey != null) {
            List<RolePermission> userRoleList = rolePermissionMapper.selectList(new QueryWrapper<RolePermission>()
                    .eq("role_key", roleKey));
            System.out.println("现在有的数据:" + userRoleList);
            if (userRoleList.size() == 0) {
                addRP = obtainPerm(addRole, roleKey);
                PlusHelper.saveBatch(addRP);
            } else {
                Set<Long> remove = userRoleList.stream().map(RolePermission::getPermKey).collect(Collectors.toSet());
                // 只需要新增的(原来有的删了)
                addRole.removeIf(remove::contains);
                System.out.println("要添加的数据:" + addRole);
                remove.removeIf(afterCopy::contains);
                System.out.println("要删除的数据:" + remove);
                addRP = obtainPerm(addRole, roleKey);
                // 添加关系
                System.out.println("添加关系:" + addRP);
                PlusHelper.saveBatch(addRP);
                if (remove.size() > 0) {
                    rolePermissionMapper.delete(new UpdateWrapper<RolePermission>().eq("role_key", roleKey).in("perm_key", remove));
                }
            }
            roleMapper.updateById(role);
        } else {
            roleMapper.insert(role);
            roleKey = role.getRoleKey();
            addRP = obtainPerm(addRole, roleKey);
            PlusHelper.saveBatch(addRP);
        }
    }

    @Override
    public void removeRole(String roleKey) {
        userRoleMapper.delete(new UpdateWrapper<UserRole>().eq("role_key", roleKey));
        rolePermissionMapper.delete(new UpdateWrapper<RolePermission>().eq("role_key", roleKey));
        roleMapper.deleteById(roleKey);
    }


    /**
     * 用于直接修改原来没有和新增
     *
     * @param perms
     * @param roleKey
     * @return
     */
    private List<RolePermission> obtainPerm(Set<Long> perms, Long roleKey) {
        List<RolePermission> urList = new ArrayList<>();
        for (Long rp : perms) {
            RolePermission userRole = new RolePermission();
            userRole.setRoleKey(roleKey).setPermKey(rp);
            urList.add(userRole);
        }
        return urList;
    }

    /**
     * 用于获取角色ID组数据
     *
     * @param split
     * @return
     */
    private Set<Long> getPermKey(String[] split) {
        Set<Long> result = new HashSet<>();
        for (String s : split) {
            if (!"".equals(s)) {
                result.add(Long.valueOf(s));
            }
        }
        return result;
    }

}
